package com.chance.cc.crawler.development.scripts.ifeng.car;

import com.alibaba.fastjson.JSONObject;
import com.chance.cc.crawler.core.CrawlerEnum;
import com.chance.cc.crawler.core.CrawlerRecordContext;
import com.chance.cc.crawler.core.downloader.HttpPage;
import com.chance.cc.crawler.core.downloader.HttpRequest;
import com.chance.cc.crawler.core.pipeline.result.CrawlerData;
import com.chance.cc.crawler.core.record.CrawlerRequestRecord;
import com.chance.cc.crawler.core.script.crawler.CrawlerCommonScript;
import com.chance.cc.crawler.core.selector.Selectable;
import com.chance.cc.crawler.core.tags.CategoryTag;
import com.chance.cc.crawler.core.tags.LabelTag;
import com.chance.cc.crawler.core.tags.crawler.CrawlerBusinessTags;
import com.chance.cc.crawler.development.scripts.allfeild.AutoVMCommonField;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import static com.chance.cc.crawler.core.CrawlerEnum.CrawlerDataType.article;


public class IFengCrawlerScript extends CrawlerCommonScript {

    private static Logger logger = LoggerFactory.getLogger(IFengCrawlerScript.class);

    public static final String beginUrl = "https://ncar.auto.ifeng.com/model/home";

    public static final String bandIdUrl = "https://api.auto.ifeng.com/api/getNewsBrands.do";

    public static final String carUrl = "https://ncar.auto.ifeng.com/model/bottomPage\\?serialId=\\d*";

    public static final String carInfoUrl = "https://api.auto.ifeng.com/api/getCarNewDeatilInfo.do\\?serialId=\\d*";

    private static final String site = "car";
    private static final String DOMAIN = "ifeng";

    private static final String REQUEST_AGAIN_TAG = DOMAIN + "_request_again";

    @Override
    public String domain() {
        return "ifeng";
    }

    @Override
    public boolean crawlerCheck(CrawlerRequestRecord crawlerRequestRecord) {
        CategoryTag categoryTag = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag();
        String crawlerSite = categoryTag.getKVTagStrVal("site");
        return crawlerSite.equalsIgnoreCase(site);
    }


    @Override
    public void initUrlRegulars() {
        addUrlRegular(beginUrl);
        addUrlRegular(bandIdUrl);
        addUrlRegular(carUrl);
        addUrlRegular(carInfoUrl);
    }

    @Override
    public List<CrawlerRequestRecord> parseLinks(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage) {
        List<CrawlerRequestRecord> parseLinksList = new ArrayList<CrawlerRequestRecord>();

        if (httpPage.getStatusCode() != 200 || (!httpPage.isDownloadSuccess())||StringUtils.isEmpty(httpPage.getHtml().get())) {
            logger.error("download page url == {} error status is {}", httpPage.getRequest().getUrl(), httpPage.getStatusCode());
            //如果没有成功的下载  进行重新下载
            this.requestAgainCrawlerRecord(parseLinksList, crawlerRequestRecord);
            crawlerRequestRecord.setNeedWashPage(false);
            return parseLinksList;
        }

        String url = httpPage.getRequest().getUrl();

        if (url.matches(beginUrl)) {
            parseBeginLinks(crawlerRequestRecord, httpPage, parseLinksList);
        }
        if (url.matches(bandIdUrl)) {
            parseBandIdLinks(crawlerRequestRecord, httpPage, parseLinksList);
        }
        if (url.matches(carUrl)) {
            parseCarLinks(crawlerRequestRecord, httpPage, parseLinksList);
        }
        return parseLinksList;
    }


    private void parseCarLinks(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerRequestRecord> parseLinksList) {
        //https://ncar.auto.ifeng.com/model/bottomPage?serialId=10800
        String url = httpPage.getRequest().getUrl();
        String serialId = url.substring(url.lastIndexOf("=") + 1);
        String infoUrl = "https://api.auto.ifeng.com/api/getCarNewDeatilInfo.do?serialId=" + serialId;

        CrawlerRequestRecord infoRecord = CrawlerRequestRecord.builder()
                .itemPageRequest(crawlerRequestRecord)
                .httpUrl(infoUrl)
                .recordKey(infoUrl)
                .releaseTime(System.currentTimeMillis())
                .copyBizTags()
                .copyResultTags()
                .build();
        infoRecord.setNeedWashPage(true);
        parseLinksList.add(infoRecord);

    }


    private void parseBandIdLinks(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerRequestRecord> parseLinksList) {
        List<Selectable> nodes = httpPage.getJson().jsonPath($_type + ".brands").nodes();


        for (Selectable node : nodes) {
            String s = node.get();
            JSONObject jsonObject1 = JSONObject.parseObject(s);
            String corps = jsonObject1.getString("corps");
            String brand = jsonObject1.getString("name");

            List corpsList = JSONObject.parseObject(corps, List.class);
            for (int i = 0; i < corpsList.size(); i++) {
                Object corpsJson = corpsList.get(i);
                if (corpsJson.toString().contains("serials")) {
                    JSONObject jsonObject = JSONObject.parseObject((String) corpsJson);

                    String brand_name = jsonObject.getString("name");
                    String brand_id = jsonObject.getString("brandId");

                    String serials = jsonObject.getString("serials");
                    List serialsList = JSONObject.parseObject(serials, List.class);
                    for (int j = 0; j < serialsList.size(); j++) {
                        Object serialsJson = serialsList.get(j);
                        JSONObject jsonObject2 = JSONObject.parseObject(serialsJson.toString());

                        String id = jsonObject2.getString("id");
                        String series = jsonObject2.getString("name");
                        String url = "https://ncar.auto.ifeng.com/model/bottomPage?serialId=" + id;
                        CrawlerRequestRecord kingRecord = CrawlerRequestRecord.builder()
                                .itemPageRequest(crawlerRequestRecord)
                                .httpUrl(url)
                                .recordKey(url)
                                .releaseTime(System.currentTimeMillis())
                                .needWashed(false)
                                .copyBizTags()
                                .copyResultTags()
                                .build();

                        kingRecord.tagsCreator().bizTags().addCustomKV("brand", brand);
                        kingRecord.tagsCreator().bizTags().addCustomKV("brand_name", brand_name);
                        kingRecord.tagsCreator().bizTags().addCustomKV("brand_id", brand_id);
                        kingRecord.tagsCreator().bizTags().addCustomKV("series", series);

                        parseLinksList.add(kingRecord);
                    }
                }
            }
        }
    }

    private void parseBeginLinks(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerRequestRecord> parseLinksList) {
        String idUrl = "https://api.auto.ifeng.com/api/getNewsBrands.do";
        CrawlerRequestRecord idRecord = CrawlerRequestRecord.builder()
                .itemPageRequest(crawlerRequestRecord)
                .httpUrl(idUrl)
                .recordKey(idUrl)
                .releaseTime(System.currentTimeMillis())
                .needWashed(false)
                .copyBizTags()
                .copyResultTags()
                .build();
        parseLinksList.add(idRecord);
    }

    @Override
    public List<CrawlerData> washPage(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage) {
        List<CrawlerData> crawlerDataList = new ArrayList<>();

        if (crawlerRequestRecord.tagsCreator().bizTags().hasKVTag("series")) {
            washCarArticle(crawlerRequestRecord, httpPage, crawlerDataList);
        }

        return crawlerDataList;
    }


    private void washCarArticle(CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, List<CrawlerData> crawlerDataList) {

        String s = httpPage.getHtml().get();
        String text = s.substring(s.indexOf("<body>") + 6, s.lastIndexOf("body") - 2);
        text = text.replaceAll("&amp;quot;", "\"");
        text = text.replaceAll("&amp;quot;", "\"");

        JSONObject jsonObject = JSONObject.parseObject(text);

        String allSold = jsonObject.getString("全部在售");
        getComment(allSold, crawlerDataList, crawlerRequestRecord, httpPage, "1");

        String theSales = jsonObject.getString("即将销售");
        getComment(theSales, crawlerDataList, crawlerRequestRecord, httpPage, "");

        String haltSales = jsonObject.getString("停售");
        getComment(haltSales, crawlerDataList, crawlerRequestRecord, httpPage, "0");

    }

    public void getComment(String allSold, List<CrawlerData> crawlerDataList, CrawlerRequestRecord crawlerRequestRecord, HttpPage httpPage, String status) {

        if (StringUtils.isNotEmpty(allSold)) {
            String url = crawlerRequestRecord.getHttpRequest().getUrl();
            String serialId = url.substring(url.lastIndexOf("=") + 1);

            String itemUrl = "https://ncar.auto.ifeng.com/model/bottomPage?serialId=" + serialId;

            String brand = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag().getKVTagStrVal("brand");
            String brand_name = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag().getKVTagStrVal("brand_name");
            String brand_id = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag().getKVTagStrVal("brand_id");
            String series = crawlerRequestRecord.tagsCreator().bizTags().getCategoryTag().getKVTagStrVal("series");

            List List = JSONObject.parseObject(allSold, List.class);
            for (int i = 0; i < List.size(); i++) {
                Object json = List.get(i);
                JSONObject Json = JSONObject.parseObject(json.toString());
                String data = Json.getString("data");
                List dataList = JSONObject.parseObject(data, List.class);

                for (int j = 0; j < dataList.size(); j++) {
                    Object o = dataList.get(j);
                    JSONObject dataJson = JSONObject.parseObject(o.toString());
                    String series_name = dataJson.getString("name");

                    series_name = series_name.replaceAll("\\n", "");
                    String series_id = dataJson.getString("id");


                    String brand_url = "https://ncar.auto.ifeng.com/model/brand?brandId=" + brand_id;

                    if (status.equals("0") || status.equals("1")) {
                        CrawlerData carData = CrawlerData.builder()
                                .data(crawlerRequestRecord, httpPage)
                                .dataId(StringUtils.joinWith("-", crawlerRequestRecord.getDomain(), article.enumVal(), serialId))
                                .resultLabelTag(CrawlerEnum.CrawlerDataType.article)
                                .url(itemUrl)
                                .releaseTime(System.currentTimeMillis())
                                .addContentKV(AutoVMCommonField.Tag_Field_Brand, brand)
                                .addContentKV(AutoVMCommonField.Field_Brand_name, brand_name)
                                .addContentKV(AutoVMCommonField.Field_Brand_url, brand_url)
                                .addContentKV(AutoVMCommonField.Field_Brand_id, brand_id)
                                .addContentKV(AutoVMCommonField.Tag_Field_Series, series)
                                .addContentKV(AutoVMCommonField.Field_Model_name, series_name)
                                .addContentKV(AutoVMCommonField.Field_Series_id, series_id)
                                .addContentKV(AutoVMCommonField.Tag_Is_sale, status)
                                .build();
                        crawlerDataList.add(carData);

                    } else {
                        CrawlerData carData = CrawlerData.builder()
                                .data(crawlerRequestRecord, httpPage)
                                .dataId(StringUtils.joinWith("-", crawlerRequestRecord.getDomain(), article.enumVal(), serialId))
                                .resultLabelTag(CrawlerEnum.CrawlerDataType.article)
                                .url(itemUrl)
                                .releaseTime(System.currentTimeMillis())
                                .addContentKV(AutoVMCommonField.Tag_Field_Brand, brand)
                                .addContentKV(AutoVMCommonField.Field_Brand_name, brand_name)
                                .addContentKV(AutoVMCommonField.Field_Brand_url, brand_url)
                                .addContentKV(AutoVMCommonField.Field_Brand_id, brand_id)
                                .addContentKV(AutoVMCommonField.Tag_Field_Series, series)
                                .addContentKV(AutoVMCommonField.Field_Model_name, series_name)
                                .addContentKV(AutoVMCommonField.Field_Series_id, series_id)
                                .build();

                        crawlerDataList.add(carData);

                    }

                }
            }
        }
    }


    @Override
    public void afterExecute(CrawlerRecordContext crawlerRecordContext) {

    }

    /*
     * 重新下载
     * */
    private void requestAgainCrawlerRecord(List<CrawlerRequestRecord> crawlerRequestRecords, CrawlerRequestRecord crawlerRecord) {
        CrawlerBusinessTags crawlerBusinessTags = crawlerRecord.tagsCreator().bizTags();
        int count = 0;
        if (crawlerBusinessTags.hasKVTag(REQUEST_AGAIN_TAG)) {
            count = (int) crawlerBusinessTags.getCategoryTag().getKVTag(REQUEST_AGAIN_TAG).getVal();
            if (count >= 10) {
                logger.error("pcauto download page the number of retries exceeds the limit" +
                        ",request url {}", crawlerRecord.getHttpRequest().getUrl());
                return;
            }
        }

        String requestUrl = crawlerRecord.getHttpRequest().getUrl();
        CrawlerRequestRecord crawlerRequestRecord = null;
        LabelTag type = crawlerRecord.tagsCreator().requestTags().getCategoryTag().getLabelTags().get("turn_page_item_request");
        if (type == null) {
            crawlerRequestRecord = CrawlerRequestRecord.builder()
                    .turnPageRequest(crawlerRecord)
                    .httpUrl(requestUrl)
                    .recordKey(crawlerRecord.getRecordKey() + count)
                    .releaseTime(crawlerRecord.getReleaseTime())
                    .notFilterRecord()
                    .copyBizTags()
                    .copyResultTags()
                    .build();
        } else {
            crawlerRequestRecord = CrawlerRequestRecord.builder()
                    .itemPageRequest(crawlerRecord)
                    .httpUrl(requestUrl)
                    .recordKey(crawlerRecord.getRecordKey() + count)
                    .releaseTime(crawlerRecord.getReleaseTime())
                    .copyBizTags()
                    .copyResultTags()
                    .build();
        }

        crawlerRequestRecord.setNeedWashPage(crawlerRecord.isNeedWashPage());
        crawlerRequestRecord.setNeedParsedPage(crawlerRecord.isNeedParsedPage());
        crawlerRequestRecord.getHttpRequest().setHeaders(crawlerRecord.getHttpRequest().getHeaders());
        crawlerRequestRecord.getHttpRequest().setExtras(crawlerRecord.getHttpRequest().getExtras());
        crawlerRequestRecord.tagsCreator().bizTags().addCustomKV(REQUEST_AGAIN_TAG, ++count);
        crawlerRequestRecords.add(crawlerRequestRecord);
    }

}
